package online.longzipeng.back.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import lombok.extern.slf4j.Slf4j;
import online.longzipeng.back.common.exception.MessageException;
import online.longzipeng.back.mapper.BillMapper;
import online.longzipeng.back.pojo.entity.Bill;
import online.longzipeng.back.pojo.param.BillQueryParam;
import online.longzipeng.back.pojo.param.PageParam;
import online.longzipeng.back.pojo.vo.BillVo;
import online.longzipeng.back.service.BillService;
import online.longzipeng.back.utils.BigDecimalUtils;
import online.longzipeng.back.utils.UserUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * @author lzp
 */
@Slf4j
@Service
public class BillServiceImpl implements BillService {

    @Autowired
    private BillMapper billMapper;

    @Override
    public JSONObject page(PageParam<BillQueryParam> param) {
        Page<BillVo> pageBill = new Page<>(param.getPage().getCurrent(), param.getPage().getSize());
        // 如果没有传团队id，那么就只查询登录用户的账单
        if (ObjectUtil.isNull(param.getParam().getTeamId()) || param.getParam().getTeamId().equals(0L)) {
            param.getParam().setUserId(UserUtils.getUserId());
        }
        pageBill = billMapper.page(pageBill, param.getParam());
        JSONObject page = new JSONObject();
        // 处理数据列表
        List<BillVo> billVos = pageBill.getRecords();
        List<JSONObject> jsonObjects = new ArrayList<>();
        /// 对数据按日期分组
        Map<String, List<BillVo>> map = billVos.stream().collect(Collectors.groupingBy(BillVo::getDateStr));
        List<String> keys = new ArrayList<>(map.keySet());
        // 对keys 按照时间大小排序
        keys = CollUtil.sort(keys, (str1, str2) -> {
            // 将字符串日期转换为 日期对象进行比较
            LocalDate date1 = LocalDate.parse(str1);
            LocalDate date2 = LocalDate.parse(str2);
            return date2.compareTo(date1);
        });
        for (String key : keys) {
            JSONObject jsonObject = new JSONObject();
            jsonObject.put("date", LocalDate.parse(key).format(DateTimeFormatter.ofPattern("MM月 dd日 E")));
            jsonObject.put("list", map.get(key));
            // 计算当日的收支和
            BigDecimal sum = BigDecimal.ZERO;
            for (BillVo billVo : map.get(key)) {
                // 0 支出  1 收入
                if (ObjectUtil.equal(billVo.getType(), Integer.valueOf("0"))) {
                    sum = sum.subtract(billVo.getMoney());
                } else {
                    sum = sum.add(billVo.getMoney());
                }
            }
            sum = BigDecimalUtils.setEffectiveNumber(sum);
            String sumStr = "小计 " + sum;
            jsonObject.put("sumStr", sumStr);
            jsonObjects.add(jsonObject);
        }
        page.put("records", jsonObjects);
        /// 处理其余分页参数
        page.put("total", pageBill.getTotal());
        page.put("size", pageBill.getSize());
        page.put("current", pageBill.getCurrent());
        // 当前数据长度，方便前端判断
        page.put("length", billVos.size());
        BillQueryParam billQueryParam = param.getParam();
        // 查询条件下的支出和
        billQueryParam.setType(0);
        page.put("expenditure", billMapper.getIncomeOrExpenditure(billQueryParam));
        // 查询条件下的收入和
        billQueryParam.setType(1);
        page.put("income", billMapper.getIncomeOrExpenditure(billQueryParam));
        return page;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void save(Bill bill) {
        // 参数校验
        if (StrUtil.isBlank(bill.getName())) {
            throw new MessageException("必须填写账单的名称！！");
        }
        // 获取登录用户的id
        Long userId = UserUtils.getUserId();
        // 如果有id，走二次编辑操作
        if (ObjectUtil.isNotNull(bill.getId())) {
            Bill billOld = billMapper.selectOne(Wrappers.<Bill>lambdaQuery().eq(Bill::getId, bill.getId()));
            BeanUtil.copyProperties(bill, billOld);
            billOld.setUpdateBy(userId);
            billMapper.updateById(billOld);
        } else {
            // 走新增
            bill.setCreateBy(userId);
            bill.setUpdateBy(userId);
            billMapper.insert(bill);
        }
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteOne(Long id) {
        billMapper.deleteById(id);
        log.info("成功删除账单：{}", id);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void delete(List<Long> ids) {
        billMapper.deleteBatchIds(ids);
        log.info("成功删除账单：{}", ids);
    }

    @Override
    public BillVo detail(Long id) {
        return billMapper.detail(id);
    }
}
